package Element;

import java.awt.*;
import java.awt.geom.*;

import Element.Geom.*;
import DistSys.*;

public class Source extends AbsElem implements Cloneable {
    public static AbsElem objActiveTemp;  //a developer's version of ActiveTemplate

    public Source(){ }

    public Object clone(){
        Source created = new Source();
        this.copyTo(created); // copy AbsElem attributes to created
        //created.setDftTemp(this.getDftTempName());
        //created.rel  = (ReliaInd) (this.rel.clone());
        //created.ckt  = (CktLaw) (this.ckt.clone());
        created.geom = (OneNodeElemGeom) (((OneNodeElemGeom)this.geom).clone());
        return created;
    }

    public int getType() {
        return (isTemplate() ? SysConst.TEMPLTYPE_SOURCE :
            SysConst.TYPE_SOURCE);
    }

    public void draw(Graphics2D g2, double dist, double theta) {
        int Ax = geom.x1 + (int)(dist * Math.cos(theta)/3);
        int Ay = geom.y1 + (int)(dist * Math.sin(theta)/3);
        int Bx = geom.x2;
        int By = geom.y2;
        int Cx = (Ax + Bx)/2;
        int Cy = (Ay + By)/2;

        g2.drawLine(geom.x1,geom.y1, Ax,Ay);     //don't rotate the handle line

        double length = Math.sqrt((double) ((Ax-Bx)*(Ax-Bx) + (Ay-By)*(Ay-By)));
        int tmp1 = (int) ((double)(Ax+Bx)/2.0 - length/2.0);
        int tmp2 = (int) ((double)(Ay+By)/2.0 - length/2.0);
        // don't use Cx - length/2 to avoid loss of precision

        g2.drawOval(tmp1,tmp2, (int)(length),(int)(length));

        Point D = new Point(), E = new Point();
        int r = (int)(length / 8.0);
        int Dx=Cx-2*r,  Dy = Cy-r;
        int Ex=Cx,      Ey = Cy-r;
        g2.drawArc(Dx, Dy, 2*r, 2*r, 0, 180 );  //draw the two arcs inside the circle
        g2.drawArc(Ex, Ey, 2*r, 2*r, 180, 180 );
    }

    /**
     * Returns whether the data field with the given index "makes sense" for
     * this element type or not.
     *
     * @param index  a <code>int</code> specifying the index.
     *
     * @return  <code>true</code> if the data field "makes sense",
     *          <code>false</code> otherwise
     */
    public boolean getDataExists(int index) {
        // A switch is used here to be independent of the
        // AbsElem.DATA_* constant's real values.
        switch(index) {
            case AbsElem.DATA_ZONE:
            case AbsElem.DATA_LAYER:
            case AbsElem.DATA_SRC_VOLT:
            case AbsElem.DATA_CONST_POWER:
            case AbsElem.DATA_PF_CONST_POWER:
            case AbsElem.DATA_RATED_POWER:
            case AbsElem.DATA_RATED_CURR:
            case AbsElem.DATA_ZONE_BUFFER0:
            case AbsElem.DATA_ZONE_BUFFER2:
            case AbsElem.DATA_ZONE_BUFFER4:
            case AbsElem.DATA_ZONE_BUFFER1:
            case AbsElem.DATA_ZONE_BUFFER3:
            case AbsElem.DATA_TEMP_FAULT:
            case AbsElem.DATA_SUST_FAULT:
            case AbsElem.DATA_OPEN_CKT:
            case AbsElem.DATA_MTTR:
            case AbsElem.DATA_RESISTANCE:
            case AbsElem.DATA_REACTANCE:
            case AbsElem.DATA_CAPITAL_COST:
            case AbsElem.DATA_OM_COST:
            case AbsElem.DATA_FONT_SIZE:
            case AbsElem.DATA_IN_OPT_LIB:
            case AbsElem.DATA_MAINT_DUR:
            case AbsElem.DATA_MAINT_RATE:
            case AbsElem.DATA_OPTIMIZABLE:
            case AbsElem.DATA_PHASE:
            case AbsElem.DATA_STUDY_AREA:
            case AbsElem.DATA_UPGRADE_COST:
            case AbsElem.DATA_YEAR:
            // added by Yanli
            case AbsElem.DATA_GEN_BUS: 
            case AbsElem.DATA_GEN_PG:
            case AbsElem.DATA_GEN_QG:
            case AbsElem.DATA_GEN_QMAX:
            case AbsElem.DATA_GEN_QMIN:
            case AbsElem.DATA_GEN_VG:
            case AbsElem.DATA_GEN_MBASE:
            case AbsElem.DATA_GEN_STATUS:
            case AbsElem.DATA_GEN_PMAX:
            case AbsElem.DATA_GEN_PMIN:
            case AbsElem.DATA_GEN_BID:
                return true;
            default:
                return false;
        }
    }

    /**
     * Returns whether the result field with the given index "makes sense" for
     * this element type or not.
     *
     * @param index  a <code>int</code> specifying the index.
     *
     * @return  <code>true</code> if the result field "makes sense",
     *          <code>false</code> otherwise
     */
    public boolean getResultExists(int index) {
        // A switch is used here to be independent of the
        // AbsElem.RES_* constant's real values.
        switch(index) {
            case AbsElem.RES_QUERY_SCORE:
            case AbsElem.RES_QUERY_SCORE_PERC:
            case AbsElem.RES_MOMENT_INT:
            case AbsElem.RES_SUST_INT:
            case AbsElem.RES_OUT_DUR:
            case AbsElem.RES_VOLT_SAGS:
            case AbsElem.RES_CAPA_CONS:
            case AbsElem.RES_CAPA_CONS_KVA:
            case AbsElem.RES_KVA_FLOW:
            case AbsElem.RES_PF:
            case AbsElem.RES_VOLT_MAG:
            case AbsElem.RES_VOLT_ANG:
            case AbsElem.RES_CURR_MAG:
            case AbsElem.RES_CURR_ANG:
            case AbsElem.RES_SHORTCIRC_CURR:
            case AbsElem.RES_VOLT_DROP:
            case AbsElem.RES_CURR_LOADING:
            case AbsElem.RES_KVA_RATING:
            case AbsElem.RES_MAIFI:
            case AbsElem.RES_SAG:
            case AbsElem.RES_SAIDI:
            case AbsElem.RES_SAIFI:
            case AbsElem.RES_VOLT_MAG_NODE1:
            case AbsElem.RES_VOLT_ANG_NODE1:
            case AbsElem.RES_VOLT_SAGS_ON_TGT:
            case AbsElem.RES_VOLT_SAGS_NODE1:
            case AbsElem.RES_PROTECT_ZONE:
            case AbsElem.RES_SA_MOMENT_INT:
            case AbsElem.RES_SA_SUST_INT:
            case AbsElem.RES_SA_DUR_SI:
            case AbsElem.RES_OLV_MI:
            case AbsElem.RES_OLV_SI:
            case AbsElem.RES_OLV_DUR_SI:
            case AbsElem.RES_UVV_MI:
            case AbsElem.RES_UVV_SI:
            case AbsElem.RES_UVV_DUR_SI:
                return true;
            default:
                return false;
        }
    }
}